/***********************************************************
**
** 作者：lth
** 日期：2016-03-09
** 描述：收发Socket数据包。
**
************************************************************/

#ifndef SOCKETCOMMUNICATION_H
#define SOCKETCOMMUNICATION_H
#include <QObject>
#include <QUdpSocket>
#include <QTcpSocket>
#include "SocketConstant.h"
#include <QTimer>
#include <QMap>
#include <QString>
#include "QpcrLog.h"
#include "ConfigFileservice.h"

class SocketClient: public QObject
{
    Q_OBJECT

protected:


private:
    QTcpSocket  *m_dataSocket;  //收发数据

    QTimer       m_diagnoseTimer; //接收到握手信号，过一段时间再判断是否还接收到

    SocketPacket m_dataPacket;
    QHostAddress m_tcpServerIP;
    int          m_tcpServerPort;
    volatile bool m_isConnecting;

public:
    SocketClient();
    QpcrLog * qpcrLog;
    ConfigFileService * cfs;
    bool isWritten;
    bool isWeihuWritten;
    bool isNotParseWritten;
    QString zhiLingString;
    QString notParseZhiling;
    QString weihuZhiling;

    /*
    工具方法
    */
    //crc
    unsigned short crc16(unsigned char *CmmBuf, unsigned char Len);
    bool        crc_Checking(QString);
    QString     crcCalculation(QString message);
    QString     returnZhiLing2Ui();
    QString     returnWeiHu2Ui();
    QString returnNotParseZhiling2Ui();

    //数据内容拼接
    QByteArray getsendData(QString deviceID, QString shiyanID,QString cmd,QString wendu);
    QByteArray getsendData(QString deviceID, QString shiyanID,QString cmd,QString wendu,QString str5);
    QByteArray getsendData(QString deviceID, QString shiyanID,QString cmd);
    QByteArray getsendData(QString shiyanID,QString cmd);
    QByteArray getsendData(QString str1, QString str2, QString str3,
                           QString str4, QString str5, QString str6, QString str7);
    bool isConnected();
    void connectTcpServer(QHostAddress ip, int port);

    /*
    此部分方法为解析收到数据的方法
    */
    bool parsePacket(QTcpSocket *socket, SocketPacket *packet);
    QStringList parsedataPacket(QString recvdata);
    QVector<QStringList> parseYingguangdataPacket(SocketPacket socketData);
    QStringList parseWeihu(QString analydata);
    QStringList analysisData(SocketPacket socketData);
    QStringList analyKuozengData(SocketPacket socketData);
    QStringList analyYangbenData(SocketPacket socketData);
    QStringList analyWenduData(SocketPacket socketData);
    QStringList analyYingguangData(QString yingguangmsg);
    QStringList analyKongweiRowData(QString kongweimsg);
    QStringList analyWeihudataPacket(SocketPacket socketData);
    QString analyIPdataPacket(SocketPacket socketData);

    /// 2023-05-07 修改，实验恢复长度330，荧光数据长度334
    /// 返回值格式{（设备ID， 实验ID, 循环数）, (32个孔位4通道荧光数据)}
    /// \brief parseShiyanYingguangdataHuifuPacket
    /// \param socketData
    /// \return
    ///
    QVector<QStringList> parseShiyanYingguangdataHuifuPacket(SocketPacket socketData);
    QStringList analyYingguangHuifuData(QString yingguangmsg);


    /*
      此部分为所有数据发送方法
    */
    void sendZijianCmd(QString deviceID);
    void sendStartCmd(QString deviceID, QString shiyanID);
    void sendStopCmd(QString deviceID, QString shiyanID,QString wendu);
    void sendContiueCmd(QString deviceID, QString shiyanID);
    void sendCloseCmd(QString deviceID, QString shiyanID);
    void sendKuozengData(QString shiyanID, QString content);
    void sendYangbenData(QString shiyanID, QString content);
    void sendYingguangData(QString deviceID, QString shiyanID);
    void sendWenduData(QString deviceID, QString shiyanID);
    void sendGuzhangData(QString deviceID, QString shiyanID);
    /// 2023-05-07 新修改
    /// \brief sendShiyanHuifuData
    /// \param deviceID
    /// \param shiyanID
    ///
    void sendShiyanHuifuData(QString deviceID, QString shiyanID);

    /*
    加热维护
    */
    void sendWeihuJiaresi(QString zhanKongbi, QString cmd);
    void sendWeihuSersorwendu(QString wendu1, QString wendu2, QString cmd);
    void sendWeihuRaoluanfeng(QString zhanKongbi, QString cmd);
    void sendWeihuRaoluanfengshanKaiguan(QString Kaiguan, QString cmd);
    void sendWeihuPaifengfengshan(QString Kaiguan, QString cmd);
    void sendWeihuDuiliufengshan(QString Zhankongbi, QString cmd);
    void sendWeihuBiaozhunWendu(QString wendu, QString cmd);
    void sendWeihuReshiyuandian(QString tongdao, QString step, QString cmd);
    //void sendWeihuXuanzhuan(QString zhuansu, QString fangxiang, QString cmd);
    void sendWeihuKongweipiancha(QString haocaitype, QString kongwei, QString yuandianpiancha,
                                              QString pingjunpiancha, QString cmd);
    /*
    荧光检测维护
    */
    void sendWeihuTongdaoKaiguan(QString tongdao, QString kaiguan, QString cmd);
    void sendWeihuTongdaozhi(QString tongdao, QString Yingguangzhi, QString AD, QString cmd);
    void sendWeihuJifaqiangdu(QString tongdao,QString qiangdu, QString cmd);
    void sendWeihuYingguangzengyi(QString tongdao, QString zengyi, QString cmd);
    /*
    状态检测维护
    */
    void sendWeihuMensuo(QString pingbi, QString kaiguan, QString cmd);
    void sendWeihuBigai(QString pingbi, QString kaiguan, QString cmd);
    void sendWeihuMensuojiaozheng(QString zhankongbi, QString cmd);

    /*
    IP地址和端口发送
    */
    void sendIP(QString ip1, QString ip2, QString ip3, QString ip4, QString port);

    /*
    16进制字符串转化，
    */
    QByteArray GetHexValue(QString str);
    char ConvertHexChar(char ch);

private:
    /*
    * 没用上得
    */
    int SignedHex2Int(QByteArray array);

signals:
    void dataZijianPacketReady(SocketPacket socketData);
    void dataWenduPacketReady(SocketPacket packet);
    void dataYingguangPacketReady(SocketPacket packet);
    void dataKuozengPacketReady(SocketPacket packet);
    void dataYangbenPacketReady(SocketPacket packet);
    void dataWeihuPacketReady(SocketPacket packet);
    void dataIPPacketReady(SocketPacket packet);
    void dataShiyanYingguangPacketReady(SocketPacket packet);
    void socketConnected(bool);


public slots:
    //发送槽函数
    void send(QByteArray data, QByteArray dataType);

    QString sendWord(QByteArray data, QByteArray dataType);
    //监听接收槽函数
    void OnReadyRead();
    //断开连接槽函数
    void OnDisconnected();
    //连接超时槽函数
    void socketTimeOut();
    //关闭连接槽函数
    void closeSocket();

};

#endif // SOCKETCOMMUNICATION_H
